package repository

import (
	"context"
	"gitee.com/geekbang/basic-go/webook/internal/domain"
	"gitee.com/geekbang/basic-go/webook/internal/repository/dao"
	"time"
)

var (
	ErrUserDuplicateEmail = dao.ErrUserDuplicateEmail
	ErrUserNotFound       = dao.ErrUserNotFound
)

type UserRepository struct {
	dao *dao.UserDAO
}

func NewUserRepository(dao *dao.UserDAO) *UserRepository {
	return &UserRepository{
		dao: dao,
	}
}

func (r *UserRepository) FindByEmail(ctx context.Context, email string) (domain.User, error) {
	// SELECT * FROM `users` WHERE `email`=?
	u, err := r.dao.FindByEmail(ctx, email)
	if err != nil {
		return domain.User{}, err
	}
	return r.daoUser2DomainUser(u), nil
}

func (r *UserRepository) Create(ctx context.Context, u domain.User) error {
	return r.dao.Insert(ctx, r.domainUser2DaoUser(u))
}

func (r *UserRepository) FindById(ctx context.Context, userId int64) (domain.User, error) {
	user, err := r.dao.FindById(ctx, userId)
	if err != nil {
		return domain.User{}, err
	}
	return r.daoUser2DomainUser(user), nil
}

func (r *UserRepository) Update(ctx context.Context, user domain.User) error {
	return r.dao.Update(ctx, r.domainUser2DaoUser(user))
}

func (r *UserRepository) domainUser2DaoUser(user domain.User) dao.User {
	var ctime int64
	if !user.Ctime.Equal(time.Time{}) {
		ctime = user.Ctime.UnixMilli()
	}
	return dao.User{
		Id:           user.Id,
		Email:        user.Email,
		Password:     user.Password,
		NickName:     user.NickName,
		BirthdayStr:  user.BirthdayStr,
		Introduction: user.Introduction,
		Ctime:        ctime,
		Utime:        0,
	}
}

func (r *UserRepository) daoUser2DomainUser(user dao.User) domain.User {
	return domain.User{
		Id:           user.Id,
		Email:        user.Email,
		Password:     user.Password,
		NickName:     user.NickName,
		BirthdayStr:  user.BirthdayStr,
		Introduction: user.Introduction,
		Ctime:        time.UnixMilli(user.Ctime),
	}
}
